package com.cmwa.solution.utils;

import java.math.BigDecimal;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

/**
 * 数字的精确运算
 * @author ex-hejm
 * @date 2018年10月12日 上午11:26:03
 */
public class NumberUtil {
	private static boolean isMatch(String regex, String str) {
		if (StringUtils.isBlank(str)) {
			return false;
		}
		Pattern pattern = Pattern.compile(regex);
		Matcher isNum = pattern.matcher(str);
		return isNum.matches();
	}

	/**
	 * <pre>
	 * <b>desc:</b> 正整数，可以带+，首位不能为0
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午4:31:37
	 * </pre>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isPositiveInteger(String str) {
		return isMatch("^\\+{0,1}[1-9]\\d*", str);
	}

	/**
	 * <pre>
	 * <b>desc:</b> 负整数，必须带-，首位不能为0 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午4:32:26
	 * </pre>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNegativeInteger(String str) {
		return isMatch("^-[1-9]\\d*", str);
	}

	/**
	 * <pre>
	 * <b>desc:</b> 整数 0、正整数、负整数
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午4:32:52
	 * </pre>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isWholeNumber(String str) {
		return isMatch("[+-]{0,1}0", str) || isPositiveInteger(str) || isNegativeInteger(str);
	}

	/**
	 * <pre>
	 * <b>desc:</b> 正小数 可以带+，首位为0，小数点后不能为0，首位不为0，小数点后为任意数字
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午4:33:36
	 * </pre>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isPositiveDecimal(String str) {
		return isMatch("\\+{0,1}[0]\\.[1-9]*|\\+{0,1}[1-9]\\d*\\.\\d*", str);
	}

	/**
	 * <pre>
	 * <b>desc:</b> 负小数 必须带-，其余同正小数 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午4:34:49
	 * </pre>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNegativeDecimal(String str) {
		return isMatch("^-[0]\\.[1-9]*|^-[1-9]\\d*\\.\\d*", str);
	}

	/**
	 * <pre>
	 * <b>desc:</b> 小数 可正可负，必须存在小数点，小数点一边不为空 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午4:35:33
	 * </pre>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isDecimal(String str) {
		return isMatch("[-+]{0,1}\\d+\\.\\d*|[-+]{0,1}\\d*\\.\\d+", str);
	}

	/**
	 * <pre>
	 * <b>desc:</b> 实数 小数或者整数 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午4:36:24
	 * </pre>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isRealNumber(String str) {
		return isWholeNumber(str) || isDecimal(str);
	}

	/**
	 * <pre>
	 * <b>desc:</b> 移除小数点末尾的0 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午5:50:09
	 * </pre>
	 * 
	 * @param num
	 * @return
	 */
	public static String removeLastZero(String num) {
		if (StringUtils.isNotBlank(num)) {
			if (num.indexOf(".") > 0) {
				num = num.replaceAll("0+?$", "");
				num = num.replaceAll("[.]$", "");
			}
			return num;
		}
		return "";
	}

	/**
	 * <pre>
	 * <b>desc:</b> 输出a除以b 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午5:44:11
	 * </pre>
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static String divide(String a, String b) {
		if (StringUtils.isNotBlank(a) && StringUtils.isNotBlank(b)) {
			if (isRealNumber(a) && isRealNumber(b)) {
				String result = new BigDecimal(a).divide(new BigDecimal(b)).toPlainString();
				return removeLastZero(result);
			}
		}
		return "";
	}

	/**
	 * <pre>
	 * <b>desc:</b> 乘法 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月27日 下午5:56:17
	 * </pre>
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static String multiply(String a, String b) {
		if (StringUtils.isNotBlank(a) && StringUtils.isNotBlank(b)) {
			if (isRealNumber(a) && isRealNumber(b)) {
				String result = new BigDecimal(a).multiply(new BigDecimal(b)).toPlainString();
				return removeLastZero(result);
			}
		}
		return "";
	}

	/**
	 * <pre>
	 * <b>desc:</b> a > b 返回 1，等于返回0，小于返回-1，其他返回-2
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月29日 上午9:47:12
	 * </pre>
	 * 
	 * @param a
	 * @param b
	 * @return
	 */
	public static int compareTo(String a, String b) {
		if (StringUtils.isNotBlank(a) && StringUtils.isNotBlank(b)) {
			if (isRealNumber(a) && isRealNumber(b)) {
				int compareTo = new BigDecimal(a).compareTo(new BigDecimal(b));
				return compareTo;
			}
		}
		return -2;
	}

	/**
	 * <pre>
	 * <b>desc:</b> 判断字符串是否为空 
	 * <b>auth:</b> ex-hejm
	 * <b>date:</b> 2018年6月28日 下午4:39:56
	 * </pre>
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isStrNull(String str) {
		if ("null".equals(str)) {
			return true;
		}
		return StringUtils.isBlank(str);
	}
	
	/**
	 * 将阿拉伯数字转成罗马数字
	 * 思路是：千位先除以1000然后模10，百位先除以100然后模10，十位先除以10然后模10，个位直接模10.
	 * @author ex-hejm
	 * @date 2018年10月12日 上午11:27:22
	 * @param strNubmer
	 * @return
	 */
	public static String convertRoman(String strNubmer) {
		String[][] str = { { "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" }, // 个位数举例
				{ "", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC" }, // 十位数举例
				{ "", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM" }, // 百位数举例
				{ "", "M", "MM", "MMM" } // 千位数举例
		};
		
		if(StringUtils.isNotBlank(strNubmer)) {
			StringBuilder strBuilder = new StringBuilder();
			int number = Integer.parseInt(strNubmer);
			strBuilder.append(str[3][number / 1000 % 10]);
			strBuilder.append(str[2][number / 100 % 10]);
			strBuilder.append(str[1][number / 10 % 10]);
			strBuilder.append(str[0][number % 10]);
			return strBuilder.toString();
		}
		return "";
	}
}
